#pragma once
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

class BGLCamera
{
public:
    static glm::mat4 CreatePerspective(float fieldOfView, float aspectRatio, float zNearPlane, float zFarPlane); //创建观察矩阵
    static glm::mat4 CreateLookAt     (const glm::vec3& eyePosition, const glm::vec3& targetPosition, const glm::vec3& up); //创建视图矩阵
    static glm::vec3 World2Screen     (const glm::vec3& obj, const glm::mat4& model, const glm::mat4& proj, const glm::vec4& viewport);  //世界坐标转换为窗口坐标
    static glm::vec3 Screen2World     (const glm::vec3& win, const glm::mat4& model, const glm::mat4& proj, const glm::vec4& viewport);  //窗口坐标转换为世界坐标

private:
    glm::vec3 m_eye;       //相机位置
    glm::vec3 m_target;    //目标的位置
    glm::vec3 m_up;        //相机的上方向
    glm::vec3 m_rotation ; //相机旋转角度

    float m_fieldOfView;   //相机视角大小
    float m_screenWidth;   //窗口的宽
    float m_screenHeight;  //窗口的高
    float m_nearPlane;     //相机最近能看的距离
    float m_farPlane;      //相机最远能看的距离

    glm::vec3 m_worldRotation; //相机绕世界坐标系的旋转角度

    glm::mat4 m_view;      //视图矩阵
    glm::mat4 m_project;   //观察矩阵

private:
    void Update();

public:
    BGLCamera();
    ~BGLCamera();

    void InitCamera(const float screenWidth, const float screenHieght);  //初始化相机

    void SetPosition      (const glm::vec3& position);                    //设置相机本身的位置
    void SetRotation      (const glm::vec3& rotation);                    //设置相机旋转角度
    void SetTargetPosition(const glm::vec3& position);                    //设置相机看向目标的位置
    void SetFieldOfView   (const float fieldOfView);                      //设置相机视角大小
    void SetScreenWidth   (const float screenWidth);                      //设置窗口的宽
    void SetScreenHeight  (const float screenHeight);                     //设置窗口的高
    void SetNearPlane     (const float nearPlane);                        //设置相机最近能看的距离
    void SetFarPlane      (const float farPlane);                         //设置相机最远能看的距离

    void Translate      (const glm::vec3& position);                      //相机本身的位置偏移
    void TargetTranslate(const glm::vec3& position);                      //相机看向目标的位置的偏移
    void Rotate         (const glm::vec3& delta);                         //相机旋转偏移角度

    void SetRotationOfWorld      (const glm::vec3& rotation);             //设置相机绕世界坐标系旋转角度
    void RotationOfWorld         (const glm::vec3& delta);                //设置相机绕世界坐标系旋转偏移角度
	
    glm::vec3     GetPosition       ();                                   //获得相机本身的位置
    glm::vec3     GetRotation       ();                                   //获得相机旋转角度
    glm::vec3     GetTargetPosition ();                                   //获得相机看向目标的位置
    float         GetFieldOfView    ();                                   //获得相机视角大小
    float         GetScreenWidth    ();                                   //获得窗口的宽
    float         GetScreenHeight   ();                                   //获得窗口的高
    float         GetNearPlane      ();                                   //获得相机最近能看的距离
    float         GetFarPlane       ();                                   //获得相机最远能看的距离
    glm::vec3     GetRotationOfWorld();                                   //获得相机绕世界坐标系旋转角度

    glm::mat4 GetView();                                                  //获得视图矩阵
    glm::mat4 GetProject();                                               //获得观察矩阵

    glm::mat4 GetMVP();
};